← 返回首页

DeepSeek V4.1 的 KV Cache 汇总:改了什么、HCA 为什么退场、CED+CSA2 复现实测

汇总篇:第 1 章取自《DeepSeek-V4.1-Flash推理加速解读》——V4.1-Flash 改了什么(四步递进的推理配置)与量化的效果账;第 2、3 章讲 KV Cache 从 MLA 基准到 V4.0 三段分段再到 V4.1 换路径的演进史与 HCA 废弃的相位根因;第 4、5 章是训练结构说明与 Qwen3.5-4B 复现实测。素材:Flash 解读、kv演进.md、复现实测.md、out/ 训练结构图 ×2、相位敏感性一篇

1. V4.1-Flash 改了什么:四步递进与量化效果账

固有瓶颈(该篇的出发点):Transformer 每一层都独立保存专属 K、V——层数与序列长一起乘,上下文一长 KV Cache 先爆。V4.1-Flash 的解法不是继续把每一份压小,而是动「谁生成、谁持有」。

架构总览:40 层主干切成两段——前 20 层因果编码器 + 后 20 层解码器,每层内含 MoE 路由(Prefill 激活 8B/token);两段之间靠 KV 投影衔接:解码器的全局 KV 不从自身生成,而由编码器最后一层隐藏态 H_20 投射得到。

flowchart TD classDef io fill:#f6f8fa,stroke:#8b949e,color:#1f2328,stroke-width:1.5px classDef enc fill:#ddf4ff,stroke:#0969da,color:#0969da,stroke-width:1.5px classDef dec fill:#fbefff,stroke:#8250df,color:#8250df,stroke-width:1.5px classDef proj fill:#fff,stroke:#d0d7de,color:#59636e,stroke-dasharray:4 3 IN["输入 tokens
文本 + 图像"]:::io subgraph ENC["因果编码器 · 20 层"] direction TB E1["层 1–20
每层内含 MoE 路由
Prefill 激活 8B/token"]:::enc end PROJ["KV 投影
每层独立投射权重
不涉及注意力 / MoE"]:::proj subgraph DEC["解码器 · 20 层"] direction TB D1["层 21–40
每层内含 MoE 路由
Decode 激活 16B/token"]:::dec end OUT["输出 tokens"]:::io IN --> ENC ENC -->|"H_20 隐藏态"| PROJ PROJ --> DEC DEC --> OUT
图 1 · 模型架构(源自《Flash 推理加速解读》):20 层编码器 + 20 层解码器,两段之间 KV 投影连接

四步递进的推理配置(该篇的主线,也是「改了啥」的完整答案):

flowchart TD classDef enc fill:#ddf4ff,stroke:#0969da,color:#0969da,stroke-width:1.5px classDef dec fill:#fbefff,stroke:#8250df,color:#8250df,stroke-width:1.5px classDef bad fill:#ffebe9,stroke:#cf222e,color:#cf222e,stroke-width:1.5px classDef good fill:#dafbe1,stroke:#1a7f37,color:#1a7f37,stroke-width:1.5px classDef io fill:#f6f8fa,stroke:#8b949e,color:#1f2328,stroke-width:1.5px subgraph OLD["无 CED · Prefill 跑满 40 层"] direction LR A1["输入
30K tokens"]:::io --> B1["编码器
20 层"]:::enc B1 --> C1["解码器
20 层
自己算 KV"]:::dec C1 --> D1["Prefill 激活
480,000 B"]:::bad end subgraph NEW["有 CED · Prefill 只跑 20 层"] direction LR A2["输入
30K tokens"]:::io --> B2["编码器
20 层"]:::enc B2 -->|"KV 投影"| C2["解码器
20 层
不重算 KV"]:::dec C2 --> D2["Prefill 激活
240,000 B"]:::good end
图 2 · CED 机制(源自《Flash 推理加速解读》):无 CED 时 Prefill 跑满 40 层;CED 只跑编码器,解码段 KV 由 H_20 投影,计算量减半
flowchart LR classDef full fill:#0969da,stroke:#0969da,color:#ffffff,stroke-width:1.5px classDef reindex fill:#54aeff,stroke:#0969da,color:#1f2328,stroke-width:1.2px classDef reuse fill:#cae8ff,stroke:#0969da,color:#1f2328,stroke-width:1.2px classDef src fill:#ddf4ff,stroke:#0969da,color:#0969da,stroke-width:1.5px ENC["编码器 · 层 1–20
正常逐层前向"]:::src --> H20["H_20 · 编码器末层隐藏态
解码段 层 21–40 全局 KV 的唯一来源"]:::src H20 -->|"KV 投影 W₂₁"| FA H20 -->|"KV 投影 W₂₅"| FB H20 -->|"KV 投影 W₂₉"| FC H20 -->|"KV 投影 W₃₃"| FD H20 -->|"KV 投影 W₃₇"| FE subgraph GA["共享组 1 · 层 21–24"] direction LR FA["层 21 · Full
投影 W₂₁(H_20) 持有
主 KV + 索引器 K + Top-K"]:::full RA["层 22 · Reuse
KV 与 Top-K 全复用"]:::reuse RB["层 23 · Reindex
复用 KV,重选 Top-K"]:::reindex RC["层 24 · Reuse
KV 与 Top-K 全复用"]:::reuse FA -.->|共享| RA FA -.->|共享| RB FA -.->|共享| RC end subgraph GB["共享组 2 · 层 25–28"] direction LR FB["层 25 · Full
投影 W₂₅(H_20) 持有
主 KV + 索引器 K + Top-K"]:::full RD["层 26 · Reuse
KV 与 Top-K 全复用"]:::reuse RE["层 27 · Reindex
复用 KV,重选 Top-K"]:::reindex RF["层 28 · Reuse
KV 与 Top-K 全复用"]:::reuse FB -.->|共享| RD FB -.->|共享| RE FB -.->|共享| RF end subgraph GC["共享组 3 · 层 29–32"] direction LR FC["层 29 · Full
投影 W₂₉(H_20) 持有
主 KV + 索引器 K + Top-K"]:::full RG["层 30 · Reuse
KV 与 Top-K 全复用"]:::reuse RH["层 31 · Reindex
复用 KV,重选 Top-K"]:::reindex RI["层 32 · Reuse
KV 与 Top-K 全复用"]:::reuse FC -.->|共享| RG FC -.->|共享| RH FC -.->|共享| RI end subgraph GD["共享组 4 · 层 33–36"] direction LR FD["层 33 · Full
投影 W₃₃(H_20) 持有
主 KV + 索引器 K + Top-K"]:::full RJ["层 34 · Reuse
KV 与 Top-K 全复用"]:::reuse RK["层 35 · Reindex
复用 KV,重选 Top-K"]:::reindex RL["层 36 · Reuse
KV 与 Top-K 全复用"]:::reuse FD -.->|共享| RJ FD -.->|共享| RK FD -.->|共享| RL end subgraph GE["共享组 5 · 层 37–40"] direction LR FE["层 37 · Full
投影 W₃₇(H_20) 持有
主 KV + 索引器 K + Top-K"]:::full RM["层 38 · Reuse
KV 与 Top-K 全复用"]:::reuse RN["层 39 · Reindex
复用 KV,重选 Top-K"]:::reindex RO["层 40 · Reuse
KV 与 Top-K 全复用"]:::reuse FE -.->|共享| RM FE -.->|共享| RN FE -.->|共享| RO end
图 3 · CSA2 机制(源自《Flash 推理加速解读》):H_20 经各层投影生成层 21–40 的主 KV(5 组各一个 Full 层持有),组内 Reindex / Reuse 复用 KV 与 Top-K

量化效果四笔账:

账目数字口径说明
CSA2 收益KV 存储容量压缩至基线 1/4全注意力层共享同一份 KV + 小型转换模块跨层映射
CED + CSA2 叠加持久化 Prefix 缓存约 1/8同一条请求的落盘口径
全局 KV890 B/token2.5 条/token ×(288 B 主记录 + 68 B 索引);V4.0 同口径约 3,514 B/token
长上下文实例31,000 token × 890 B = 27.6 MB,↓75%该篇同源数字(持久化缓存/SSD 口径)

FP4 的位置:主 KV 从 FP8 下到 FP4(E2M1,每 16 通道一个 E4M3 scale,无 per-tensor scale)——这是在 CED 和 CSA2 已减过份数之后的动作,不是全局一刀切:SWA KV 仍保留 FP8。主记录 512 值 × FP4 = 256 B 加 32 B scale;索引 128 值 × FP4 = 64 B 加 4 B scale。省掉二级全局 scale 的数值前提:E2M1 只有 1 位尾数,实际 KV 最大幅度约 10,scale 上界约 2048,余量近两个数量级。

# FP4 E2M1 主 KV 量化,per-16-channel E4M3 scale
def quantize_fp4_e2m1(x):                    # x: [..., 512]
    x = x.view(..., 512 // 16, 16)           # 每 16 通道一组
    scale = x.abs().amax(dim=-1) / 6.0       # 6 = E2M1 最大幅值
    scale = scale.clamp(min_e4m3, max_e4m3)  # 无 per-tensor scale
    q = (x / scale.unsqueeze(-1)).round()    # 4 bit 量化
    return q, scale                           # 256 B + 32 B = 288 B

2. KV Cache 演进:MLA → V4.0 三段分段 → V4.1 换路径

台阶总览:MLA 基准 70,272 B/token → V4.0 约 3,514 B/token → V4.1 约 890 B/token。三个阶段压的是不同的东西:MLA 压每层存什么;V4.0 压序列维度(按时长分段);V4.1 压份数(换生成路径 + 层间复用)。

基准 MLA:特征维低秩——不为每个 head 存完整 K/V,存 512 维 latent 加 64 维 RoPE key,每 token 每层 576 标量;61 层线性累加到 70,272 B/token。层与层之间没有连线:各自生成、各自持有,「每层各存一份」这个乘数没动。

flowchart LR subgraph L1["层号(竖排)"] direction TB A1["Layer 1
h_t → Q/K/V
→ W_DKV 下投影"] A2["Layer 2
h_t → Q/K/V
→ W_DKV 下投影"] A3["Layer 3
h_t → Q/K/V
→ W_DKV 下投影"] AD["..."] A61["Layer 61
h_t → Q/K/V
→ W_DKV 下投影"] end A1 --> P1["latent 512 + RoPE 64
= 576 标量 × 2 B
= 1,152 B/token"] A2 --> P2["1,152 B/token"] A3 --> P3["1,152 B/token"] AD --> PD["..."] A61 --> P61["1,152 B/token"] P1 --> SUM["全局 KV = 61 × 1,152 B
= 70,272 B/token"] P61 --> SUM
图 4 · MLA 基准:每层独立低秩,61 × 1,152 B = 70,272 B/token——压的是每层存什么,份数乘数未动

V4.0 的三段分段:在特征维度之外沿序列维度加压,且按上下文长度分段:

上下文区间注意力类型压缩比重叠角色
0–4KFull-Attn不压缩—近处保留原始 KV,保证短距精度
4K–100KCSA4:1有,4 token近中程稀疏检索,带 Indexer
超过 100KHCA128:1无远程极粗压缩,省容量,无 Indexer

CSA 段:步长 4、窗口 8、重叠 4,块间保留一半重叠——这个重叠是它在边界处不崩的原因。21 层 CSA 主 KV 合计约 3,066 B/token,是 V4.0 全局 KV 的大头。

flowchart LR subgraph L2["CSA 层号(竖排)"] direction TB B2["Layer 2
h_t → Q/K/V
→ 4:1 压缩 + Indexer"] B3["Layer 3
h_t → Q/K/V
→ 4:1 压缩 + Indexer"] B4["Layer 4
h_t → Q/K/V
→ 4:1 压缩 + Indexer"] BD1["..."] B22["Layer 22
h_t → Q/K/V
→ 4:1 压缩 + Indexer"] end B2 --> C2["Q 查 Top-K 压缩块
K/V 压成 4:1 entry
步长 4,窗口 8,重叠 4
146 B/token"] B3 --> C3["146 B/token"] B4 --> C4["146 B/token"] BD1 --> CD1["..."] B22 --> C22["146 B/token"] C2 --> CHUNK["切块:token 0-7 窗口 8
token 4-11 窗口 8,重叠 4
token 8-15 窗口 8,重叠 4"] C3 --> CHUNK C4 --> CHUNK CD1 --> CHUNK C22 --> CHUNK CHUNK --> SUM2["21 层 CSA
21 × 146 ≈ 3,066 B/token"]
图 5 · V4.0 CSA:21 层 × 146 B ≈ 3,066 B/token,4:1 带重叠 + Indexer Top-K

HCA 段:每 128 个 token 压成一条 entry,块间首尾相接、没有重叠;每层 query 直接看全部压缩块(无 Indexer)。20 层 HCA 合计仅约 91 B/token——省,但把风险集中在边界上(第 3 章展开)。

flowchart LR subgraph RAW["原始 token(最左列)"] direction TB R1["token 0–127"] R2["token 128–255"] R3["..."] R4["token 3968–4095"] end R1 -->|"128:1"| K1["压缩块 A
1 条 entry"] R2 -->|"128:1"| K2["压缩块 B
1 条 entry"] R3 -->|"128:1"| KD["..."] R4 -->|"128:1"| K4["压缩块 32
1 条 entry"] subgraph L3["HCA 层号(竖排)"] direction TB D23["Layer 23
h_t → Q/K/V
Q 看全部压缩块"] D24["Layer 24
h_t → Q/K/V
Q 看全部压缩块"] D25["Layer 25
h_t → Q/K/V
Q 看全部压缩块"] DD2["..."] D42["Layer 42
h_t → Q/K/V
Q 看全部压缩块"] end K1 --> D23 K2 --> D23 KD --> D23 K4 --> D23 D23 --> H23["无重叠,无 Indexer
4.56 B/token/层"] D24 --> H24["4.56 B/token/层"] D25 --> H25["4.56 B/token/层"] DD2 --> HD2["..."] D42 --> H42["4.56 B/token/层"] H23 --> BOUNDARY["边界问题
query 在 127/128 边界
证据被切到相邻块
最坏检索 -40%"] H24 --> BOUNDARY H25 --> BOUNDARY HD2 --> BOUNDARY H42 --> BOUNDARY BOUNDARY --> SUM3["20 层 HCA
20 × 4.56 ≈ 91 B/token
V4.0 总全局 ≈ 3,514 B/token"]
图 6 · V4.0 HCA:128:1 无重叠,20 × 4.56 ≈ 91 B/token;V4.0 全局合计约 3,514 B/token

V4.1 的两件事:一是 CED 拆分——后 20 层的全局 KV 从 H_20 投影分发,不再逐层自产,全局 KV 生成维度上 40 层工作量接近减半;二是 CSA2 层间复用——Full 层完整生成主 KV 和 indexer K,Reindex 层共享主 KV 只重算 Top-K,Reuse 层连索引也复用,真正独立持有全局 KV 的只剩少数源层。压缩比从 4 降到 2(步长 2、窗口 4、重叠 2)。

flowchart LR subgraph LAYERS["层号(竖排)"] direction TB E1["Layer 1
h_t → Q/K/V
→ CSA2 2:1 编码"] E2["Layer 2
h_t → Q/K/V
→ CSA2 2:1 编码"] E3["Layer 3
h_t → Q/K/V
→ CSA2 2:1 编码"] ED["..."] E20["Layer 20
h_t → Q/K/V
→ CSA2 2:1 编码"] D21["Layer 21
从 H_20 投影得 KV
→ CSA2 Full"] D22["Layer 22
从 H_20 投影得 KV
→ CSA2 Reindex"] D23["Layer 23
从 H_20 投影得 KV
→ CSA2 Reuse"] DD["..."] D40["Layer 40
从 H_20 投影得 KV
→ CSA2 Reuse"] end subgraph ENC["前 20 层:Causal Encoder"] direction TB EN1["逐层编码"] --> EN2["汇总全部上下文"] EN2 --> H20["H_20
Encoder 最终隐藏状态
一份浓缩摘要"] end E1 --> EN1 E2 --> EN1 E3 --> EN1 ED --> EN1 E20 --> EN1 subgraph PROJ["投影分发(一次 matmul,无 attention)"] direction TB P["每层独立投影权重 W
从 H_20 取出该层全局 KV"] end H20 --> P subgraph DEC["后 20 层:Decoder(CSA2)"] direction TB DF["Full 层
持有主 KV + indexer K"] DR["Reindex 层
共享主 KV,重算 Top-K"] DU["Reuse 层
直接复用,不新增"] end P --> DF P --> DR P --> DU D21 -.-> DF D22 -.-> DR D23 -.-> DU DD -.-> DU D40 -.-> DU DF --> SUM4["全局 KV = 890 B/token
2.5 条/token × (288 + 68) B"] DR --> SUM4 DU --> SUM4
图 7 · V4.1 CED + CSA2:H_20 投影分发(一次 matmul)+ Full/Reindex/Reuse 复用 → 全局 890 B/token

3. HCA 为什么退场:无重叠的相位代价

根因一条:128:1 压缩且块间无重叠——query 落在 127/128 这类边界时,需要的证据被切到相邻块。字节 Seed 实测里,V4-Flash 在 128K 检索任务中最好与最差位置组的准确率差约 40 个百分点,波动周期与分块步长一致。站内《固定窗口压缩的相位敏感性》一篇专门展开了这个现象。

flowchart LR subgraph L5["Decoder 层号(竖排,原 HCA 位置)"] direction TB G23["Layer 23
从 H_20 投影得 KV
h_t → Q/K/V"] G24["Layer 24
从 H_20 投影得 KV
h_t → Q/K/V"] G25["Layer 25
从 H_20 投影得 KV
h_t → Q/K/V"] GD2["..."] G40["Layer 40
从 H_20 投影得 KV
h_t → Q/K/V"] end G23 --> COMPARE["同一段层,两代处理方式"] G24 --> COMPARE G25 --> COMPARE GD2 --> COMPARE G40 --> COMPARE COMPARE --> OLD["V4.0 这段:HCA 128:1
每层自己从 h_t 生成 KV
无重叠,无 Indexer
4.56 B/token/层
边界最坏 -40%"] COMPARE --> NEW["V4.1 这段:从 H_20 投影得 KV
K/V → CSA2 2:1 带重叠
带 Indexer,Q 查 Top-K
100K 门限作废
4K–1M 全 CSA2"] OLD --> RESULT["最坏相位劣化
40% → 约 6%
没有清零"] NEW --> RESULT
图 8 · 同一段层的两代处理:HCA 128:1 无重叠 → CSA2 2:1 带重叠带 Indexer,最坏相位劣化约 40% → 约 6%

三条边界要交代:

4. 训练说明:老师-学生结构与三段关键代码

训练结构(参考图):老师是 SWA(滑动窗口 128,冻结 ❄),学生在 SWA 之外多出一条可学习的 KV 分支(θ 标记为可训练参数)——HCA 版把历史压成 128:1 无重叠的压缩条目 + 滑窗原始 KV 做 Shared-KV MQA;CSA 版用 4:1 重叠压缩 + Lightning Indexer 打分选 Top-K,Indexer 因 Top-K 掩码不可导而加辅助损失 L_idx。

输入 Hidden States H 👨‍🏫 老师 · SWA(滑动窗口 · 冻结 ❄) 输入 H LayerNorm Q 投影 K 投影 V 投影 滑窗 MQA 仅最近 128 token 仅最近 128 token O 投影 ⊕ 残差 FFN (SwiGLU) ⊕ 残差 输出 H′ 🧑‍🎓 学生 · SWA + HCA(KV 学习分支为重点) 输入 H LayerNorm KV 学习分支(HCA · 可学习) 压缩权重 Z = H·W^Z θ: W^Z·B KV 投影 C = H·W^KV θ: W^KV S = Softmax(Z_block + B) C^Comp = Σ S_j ⊙ C_j 128:1 无重叠 · 仅本块 最近滑窗原始 KV (取最近窗口 · 经 W^KV) 低秩 Q 投影 θ: W^DQ·W^UQ c^Q = h·W^DQ → q = c^Q·W^UQ Shared-KV MQA K = V = 压缩条目 + 滑窗原始 KV K = V = 压缩条目 + 滑窗原始 KV O 投影 ⊕ 残差 θ: W_O θ: W_O FFN (SwiGLU) ⊕ 残差 输出 H′ Loss 计算 (LM 损失 + 蒸馏对齐) 压缩 KV(K=V) 原始 KV(局部兜底) 教师输出 · 软标签 学生输出 · 预测 梯度回传(仅学生 θ) 更新 W^DQ、W^UQ 更新 W^Z、B 更新 W^KV 红色虚线 = 梯度回传(仅学生侧参数 θ 被更新) 灰色节点 = 老师(SWA,❄ 冻结,无梯度) 黄色虚线框 = KV 学习分支(本图重点:公式与参数齐全;图 2 无 Indexer,全程可导)
图 9 · 训练结构·学生 SWA + HCA 分支:压缩权重 Z=H·W^Z 经 Softmax 聚合,128:1 无重叠 + 滑窗原始 KV,低秩 Q 投影
输入 Hidden States H 👨‍🏫 老师 · SWA(滑动窗口 · 冻结 ❄) 输入 H LayerNorm Q 投影 K 投影 V 投影 滑窗 MQA 仅最近 128 token 仅最近 128 token O 投影 ⊕ 残差 FFN (SwiGLU) ⊕ 残差 输出 H′ 🧑‍🎓 学生 · SWA + CSA(KV 学习分支为重点) 输入 H LayerNorm KV 学习分支(CSA · 可学习) 压缩权重 Z = H·W^Z θ: W^Z·B KV 投影 C = H·W^KV θ: W^KV S = Softmax(Z_block + B) C^Comp = Σ S_j ⊙ C_j 4:1 重叠 · 当前块+前一块 Lightning Indexer 打分选 Top-K · θ: W_idx 打分选 Top-K · θ: W_idx Indexer 辅助损失 L_idx (Top-K 掩码不可导) Q 投影 θ: W_Q θ: W_Q 稀疏 MQA 仅 Top-K 块 · K = V = 压缩条目 仅 Top-K 块 · K = V = 压缩条目 O 投影 ⊕ 残差 θ: W_O θ: W_O FFN (SwiGLU) ⊕ 残差 输出 H′ Loss 计算 (LM 损失 + 蒸馏对齐) 压缩条目 索引分数 压缩 KV(K=V) Top-K 掩码 教师输出 · 软标签 学生输出 · 预测 梯度回传(仅学生 θ) 更新 W_Q 更新 W^Z、B 更新 W^KV 更新 W_idx 红色虚线 = 梯度回传(仅学生侧参数 θ 被更新) 灰色节点 = 老师(SWA,❄ 冻结,无梯度) 黄色虚线框 = KV 学习分支(本图重点:公式与参数齐全) 橙色节点 = Indexer 辅助损失(Top-K 掩码不可导,仅图 1 有)
图 10 · 训练结构·学生 SWA + CSA 分支:4:1 重叠(当前块+前一块)+ Lightning Indexer 选 Top-K + 辅助损失 L_idx

复现侧的三段核心代码(完整版见复现实测.md):CED 主投影器 Linear(2560, 2048) 约 5.24M 参数,输出前 1024 维作 K、后 1024 维作 V:

class CEDProjector(nn.Module):
    """Linear(hidden -> 2*KV_DIM),输出前 1024 为 K、后 1024 为 V"""

    def __init__(self, input_dim=config.PROJ_INPUT_DIM, output_dim=config.PROJ_OUTPUT_DIM):
        super().__init__()
        self.proj = nn.Linear(input_dim, output_dim, bias=True)

    def forward(self, h16: torch.Tensor):
        out = self.proj(h16)
        return out[..., : out.shape[-1] // 2], out[..., out.shape[-1] // 2 :]

CSA2 适配器:闭式解线性基座 + 残差修正。这里踩过一个坑——ResidualMLP 若前后两层都零初始化,梯度恒为零,残差分支成死区;改成只零初始化最后一层、前层随机初始化后,V 的 R² 从 0.57~0.69 提升到 0.67~0.83:

class ResidualMLPAdapter(nn.Module):
    """闭式解线性基座 + 残差修正:y = base(x) + refine(x)。
    refine 末层零初始化(起点等价闭式解);前层保持默认随机初始化——
    若两层全零,W1/W2 梯度恒为零,残差分支成死区(已踩坑,勿改回)。"""

    def __init__(self, dim, hidden=None):
        super().__init__()
        hidden = hidden or dim * 2
        self.base = nn.Linear(dim, dim)
        self.refine = nn.Sequential(
            nn.Linear(dim, hidden), nn.GELU(), nn.Linear(hidden, dim)
        )
        nn.init.zeros_(self.refine[2].weight)
        nn.init.zeros_(self.refine[2].bias)

    def forward(self, x):
        return self.base(x) + self.refine(x)

岭回归闭式解初始化:让适配器起点等价于「最优线性映射」,SGD 只补非线性残差:

@torch.no_grad()
def init_from_closed_form(self, x_k, y_k, x_v, y_v, lam=1.0):
    """闭式解(岭回归)初始化:x (N,dim) -> y (N,dim)。
    Linear:直接求解;ResidualMLP:初始化 base 分支(refine 保持零)。"""
    for map_module, x, y in ((self.k_map, x_k, y_k), (self.v_map, x_v, y_v)):
        target = map_module if isinstance(map_module, nn.Linear) else map_module.base
        xa = torch.cat([x, torch.ones(x.shape[0], 1, device=x.device)], dim=1)
        w = torch.linalg.solve(xa.T @ xa + lam * torch.eye(xa.shape[1], device=x.device), xa.T @ y)
        target.weight.copy_(w[:-1].T)
        target.bias.copy_(w[-1])

5. 复现实测:设定、结果与边界

设定:Qwen3.5-4B 冻结主干,hook 一次 forward 捕获第 16 层隐藏态 H_16 与第 20/24/28/32 层的 k_proj/v_proj 输出(pre-norm、pre-RoPE 空间),1200 条样本落盘 12.2GB;CED 投影器 MSE 收敛 0.0658。与官方的关键差异:官方是从头预训练时协同学习投影器与适配器,复现是在已收敛表示空间里做映射拟合——验证的是机制可行性,不是原始训练配方。

flowchart TD A[输入 tokens] --> B["layers 0..15
编码段"] B --> C["H_16
第16层隐藏态 (L, 2560)"] C --> D["P(H_16)
Linear 2560→2048"] D --> E["K_20, V_20
(L, 1024) × 2"] C --> F["layers 16..31
解码段"] E --> F F --> G[输出 logits]
图 11 · CED 在 32 层里的位置:第 16 层切分,H_16 经 Linear 2560→2048 投影出解码段全注意力层的 KV
flowchart TD A["第20层
Full 模式
K_20, V_20"] --> B["K_20, V_20
1 份存储"] B --> C["第24层适配器
K: Linear
V: ResidualMLP"] B --> D["第28层适配器
K: Linear
V: ResidualMLP"] B --> E["第32层适配器
K: Linear
V: ResidualMLP"] C --> F["K_24, V_24"] D --> G["K_28, V_28"] E --> H["K_32, V_32"]
图 12 · CSA2 共享机制:只保留第 20 层 1 份 KV,第 24/28/32 层各挂小适配器做跨层映射(每层约 1M 参数)
flowchart TD A["输入 tokens"] --> B["编码段 layers 0..15"] B --> C["H_16"] C --> D["CED 投影器 P
Linear 2560→2048"] D --> E["K_20, V_20
全量 KV"] E --> F["CSA2 适配器 × 3
→ K_24/V_24, K_28/V_28, K_32/V_32"] F --> G["TurboQuant k8v4
K 8bit / V 4bit"] G --> H["解码段 attention
layers 16..31"] H --> I["输出 logits"]
图 13 · 三者叠加的数据流:CED 投影 → CSA2 共享 → TurboQuant k8v4 量化 → 解码段 attention

四项主要结果:

指标baselineCED + CSA2 / 量化判定
GSM8K(100 题)0.7600.750(-1pp)基本无损
NIAH(50 条,8K 上下文)0.9400.920(-2pp)基本无损
Prefill 延迟 @2048 / 1024 / 512589.9 ms387.9 ms;1.56x / 1.27x / 1.18x加速成立,随长度增长
KV 解码段压缩(持久口径)1x3.44x(L 大时趋近 4x)达标
KV 全模型压缩(持久口径)1x1.60x(=理论 8/5)达标
k8v4 量化压缩比1x2.46x(理论 2.53x)达标
k8v4 top-5 重合 / top-1 一致—100% / 88.9%轻微扰动
两个必须说清的口径(易误读) 持久 ≠ 驻留:3.44x 是落盘/最小集合口径;运行时 reuse 层的物化视图仍占 HBM,驻留口径约 1.00x——当前实现是「落盘压缩 + 计算复用」,不是显存压缩,显存 4x 需要 attention 内惰性物化(后续工作)。
mode_b 有适用边界:解码段含 24 层 GatedDeltaNet(递归结构),从零状态起步无法携带历史——mode_b 适合 prefill 延迟优化与 next-token 评测,连续生成要走 mode_csa2_adapter;只旁路 4 个全注意力层时加速从 1.52x 回落 1.10x,这是架构约束不是实现 bug。

可信度交叉验证:手动逐层 decode 与官方 forward 的 max|Δlogit| = 0.0000、top-1 完全一致;固定位置 H_16 在总长 32~256 下 fp32 零差异(因果性严格);分块 kernel 对末尾不完整 chunk 的 ~2^-5 量级差异与后缀内容无关,确认为非因果泄漏。关键前提一条:跨层 KV 不能直接复用——第 20 层与第 24/28/32 层 KV 余弦相似度约 0,必须经可训练适配器映射,映射后 R² 到 0.67~0.85。

6. 结论与来源

结论三句:演进主线索是「压每份 → 压序列 → 压份数」,V4.1 用 CED+CSA2 换掉逐层自产,用带重叠的 CSA2 接住 HCA 退场后的远程段,FP4 收位宽,全局 890 B/token、持久化 1/8;相位问题从 40pp 压到约 6pp 但未消除;复现侧在 4B 混合架构上验证机制成立——生成质量基本无损、prefill 加速与持久压缩达标、量化扰动轻微,规模与架构差异是结论的边界。

来源与互链:第 1 章与图 1–3 取自站内《DeepSeek-V4.1-Flash 推理加速解读》(四步递进的推理配置与量化效果);HCA 相位现象的专门展开见《DeepSeek-V4.1 固定窗口压缩的相位敏感性》;第 2、3 章基于 KV 演进底稿(图 4–8),第 4、5 章基于 CED+CSA2 复现实测记录(图 9–13 与四段代码);训练结构参考图为老师-学生 SWA 结构两式(HCA / CSA)。

汇总篇 · 2026-10-19 发布 · 第 1 章图 1–3 取自《Flash 推理加速解读》,相位现象详见《固定窗口压缩的相位敏感性》;数字与结论均取自所引素材

华杉的技术博客 · 苏ICP备2026063680号-1
首页